import _ from 'lodash';
import { resolve } from 'path';
export const controller = new AbortController();

const signal = controller.signal;
// controll.abort() 终止请求
export const json2formData = (jsonData:Object) => {
    const formData = new FormData();
    _.forEach(jsonData,(value:any,key:string) => formData.append(key,value));
    return formData;
}
interface setBodyProps {
    contentType:string;
    body:Object;
}
export const setBody = ({contentType,body}:setBodyProps)=>{
    if(!contentType) return;
    if(!body) return;
    const dict:any = {
        'application/json':JSON.stringify(body),
        'application/x-www-form-unlencoded':json2formData(body),
        'mutipart/form-data':json2formData(body)
    }
    return dict[contentType];
}

interface FeatchOptions {
    method?:string;
    credentials?:RequestCredentials;
    mode?:RequestMode;
    redirect?:RequestRedirect;
    headers?:HeadersInit;
    signal?:AbortSignal;
    body?:BodyInit | null;
}

export default (url:string,options?:FeatchOptions) => {
    return new Promise((resolve,reject)=>{
        if(!url){
            reject({msg:'没有传递URL地址',status:400})
        }
        let headers:HeadersInit = _.get(options,'headers',{
            // "Content-Type": "application/json", <= POST => body: JSON.stringify({})
            // "Content-Type": "application/x-www-form-urlencoded", <= POST => body: new FormData()
            // "Content-Type": "multipart/form-data",
            // "Content-Type": "text/plain",
            // "Content-Type": "text/html", <= GET
            'Content-Type':_.get(options,'headers["Content-Type]','application/json') || _.get(options,'headers["content-type"]','application/json')
        })
        let fetchOptions:FeatchOptions = {
            method:_.get(options,'method','GET'),
            signal:signal,
            credentials:_.get('options','credentials','include'),
            headers:headers,
            mode:_.get(options,'mode','cors'),
            redirect:_.get(options,'redirect','follow')
        };
        if(_.includes(['GET','get'],_.get(options,'methods','GET'))){
            var searchQuery = _.join(_.map(_.get(options,'body'),(value:any,key:string)=>`${key}=${value}`),'&')
            if(searchQuery){
                url+='?'+searchQuery;
            }
        }else{
            const bodyData = _.get(options,'body',{});
            if(_.isObject(bodyData)&&(bodyData instanceof FormData)){
                _.set(fetchOptions,'Content-Type','multipart/form-data')
            }else{
                let contentType = _.lowerCase(_.get(headers,'Content-Type'));
                _.set(fetchOptions,'body',setBody({contentType,body:bodyData}))
            }
        }
        fetch(url,{...fetchOptions}).then(res=>{
            // 判断返回类型
            // return res.json()
            // return res.text()
            // return res.blob()
            if(res?.json){
                return res.json()
            }else if(res?.text){
                return res.text()
            }else if(res?.formData){
                return res.formData()
            }else if(res?.blob){
                return res.blob()
            }else if(res?.arrayBuffer){
                return res.arrayBuffer();
            }
        }).then(data=>{
            resolve(data)
        }).catch(error=>{
            reject(error);
            throw new Error(error);
        })

    })
}